#!/bin/sh
#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
set +x
#@function: backup oracle archive log

SCRIPT_ROOT_PATH=$1
PID=$2
PARAM_NUM=$3
SCRIPTPID=$$

. "${SCRIPT_ROOT_PATH}/oracle_sbin_func.sh"
. "${SCRIPT_ROOT_PATH}/oracle_native_archive_backup_func.sh"

echo ${SCRIPTPID} > "${SCRIPTPID_FILE}"

#********************************define these for local script********************************

PARAM_CONTENT=`read_input_param "${PARAM_NUM}"`
test -z "$PARAM_CONTENT"                                       && exit_with_error "PARAM_FILE"
#
##############################################################
DBNAME=`get_value "${PARAM_CONTENT}" AppName`
DBUUID=`get_value "${PARAM_CONTENT}" DBUUID`
DBINSTANCE=`get_value "${PARAM_CONTENT}" InstanceName`
DBUSER=`get_value "${PARAM_CONTENT}" UserName`
DBUSERPWD=`get_value "${PARAM_CONTENT}" Password`
IN_ORACLE_HOME=`get_value "${PARAM_CONTENT}" OracleHome`
ASMUSER=`get_value "${PARAM_CONTENT}" ASMUserName`
ASMUSERPWD=`get_value "${PARAM_CONTENT}" ASMPassword`
CHANNELS=`get_value "${PARAM_CONTENT}" Channel`
ARCHIVE=`get_value "${PARAM_CONTENT}" LogPath`
QOS=`get_value "${PARAM_CONTENT}" Qos`
TRUNCATELOG=`get_value "${PARAM_CONTENT}" truncateLog`
ASMSIDNAME=`get_value "${PARAM_CONTENT}" ASMInstanceName`
ENCALGO=`get_value "${PARAM_CONTENT}" EncAlgo`
ENCKEY=`get_value "${PARAM_CONTENT}" EncKey`
LAST_BACKUP_SCN=`get_value "${PARAM_CONTENT}" LastBackupScn`
LAST_BACKUP_RESET_LOGS_ID=`get_value "${PARAM_CONTENT}" LastBackupResetLogsId`
ORA_DB_USER=`get_value "${PARAM_CONTENT}" OracleInstallUser`
ORA_GRID_USER=`get_value "${PARAM_CONTENT}" GridInstallUser`
IPPORTINFO=`get_value "${PARAM_CONTENT}" IpPortInfo`
NODENUMBER=`get_value "${PARAM_CONTENT}" NodeNumber`
ORACLE_BASE=`get_value "${PARAM_CONTENT}" AccessOracleBase`
ORACLE_HOME=`get_value "${PARAM_CONTENT}" AccessOracleHome`
PDB_TAG=`get_value "${PARAM_CONTENT}" PdbTag`
PARENT_NAME=`get_value "${PARAM_CONTENT}" ParentName`


test "$DBNAME" = "ERROR_PARAM_INVALID"                          && exit_with_error "DBNAME"
test "$DBUUID" = "ERROR_PARAM_INVALID"                          && exit_with_error "DBUUID"
test "$DBINSTANCE" = "ERROR_PARAM_INVALID"                      && exit_with_error "DBINSTANCE"
test "$DBUSER" = "ERROR_PARAM_INVALID"                          && exit_with_error "DBUSER"
test "$IN_ORACLE_HOME" = "ERROR_PARAM_INVALID"                  && exit_with_error "IN_ORACLE_HOME"
test "$ASMUSER" = "ERROR_PARAM_INVALID"                         && exit_with_error "ASMUSER"
test "$CHANNELS" = "ERROR_PARAM_INVALID"                        && exit_with_error "CHANNELS"
test "$ARCHIVE" = "ERROR_PARAM_INVALID"                         && exit_with_error "ARCHIVE"
test "$QOS" = "ERROR_PARAM_INVALID"                             && exit_with_error "QOS"
test "$TRUNCATELOG" = "ERROR_PARAM_INVALID"                     && exit_with_error "TRUNCATELOG"
test "$ASMSIDNAME" = "ERROR_PARAM_INVALID"                      && exit_with_error "ASMSIDNAME"
test "$ENCALGO" = "ERROR_PARAM_INVALID"                         && exit_with_error "ENCALGO"
test "$LAST_BACKUP_SCN" = "ERROR_PARAM_INVALID"                 && exit_with_error "LAST_BACKUP_SCN"
test "$LAST_BACKUP_RESET_LOGS_ID" = "ERROR_PARAM_INVALID"       && exit_with_error "LAST_BACKUP_RESET_LOGS_ID"
test "$NODENUMBER" = "ERROR_PARAM_INVALID"                      && exit_with_error "NODENUMBER"
test "$PDB_TAG" = "ERROR_PARAM_INVALID"                         && exit_with_error "PDB_TAG"
test "$PARENT_NAME" = "ERROR_PARAM_INVALID"                     && exit_with_error "PARENT_NAME"

log_info "PID=${PID};DBINSTANCE=${DBINSTANCE};DBNAME=${DBNAME};DBUUID=${DBUUID};DBUSER=${DBUSER};ASMInst=${ASMSIDNAME};\
ASMUSER=${ASMUSER};DBCHANNEL=${CHANNELS};ARCHIVE=${ARCHIVE};QOS=${QOS};TRUNCATELOG=${TRUNCATELOG};ENCALGO=${ENCALGO};\
LAST_BACKUP_SCN=${LAST_BACKUP_SCN};LAST_BACKUP_RESET_LOGS_ID=${LAST_BACKUP_RESET_LOGS_ID};\
IPPORTINFO=${IPPORTINFO};NODENUMBER=${NODENUMBER};ORACLE_BASE=${ORACLE_BASE};ORACLE_HOME=${ORACLE_HOME};\
PDB_TAG=${PDB_TAG};PARENT_NAME=${PARENT_NAME}."

test -z "$ARCHIVE"     && exit_with_error "log path"
test -z "$DBINSTANCE"  && exit_with_error "oracle instance name"
test -z "${DBUUID}"    && exit_with_error "db uuid"

if [ -z "$QOS" ]; then
    QOS=0
fi
if [ -z "${CHANNELS}" ] || [ "${CHANNELS}" -eq 0 ]; then 
    CHANNELS=4
    log_warn "Setting channels number to ${CHANNELS} by default"
fi

if [ "${CHANNELS}" -gt 254 ]; then
    log_error "Channels param is invalid "
    exit "${RETURN_INVALID}"
fi

IS_ENC_BK=0
if [ -n "${ENCALGO}" ] && [ -n "${ENCKEY}" ]; then
    IS_ENC_BK=1
    RMAN_ENC_SECTION="configure encryption for database on; configure encryption algorithm '${ENCALGO}'; set encryption on identified by \"${ENCKEY}\" only; set decryption identified by \"${ENCKEY}\";"
    log_info "Backup database will enc "
fi

#********************************check host enviroment begin********************************
#get oracle user info
get_oracle_user
get_oracle_user_shell_type
env_file_list=`get_user_env_file "${ORA_DB_USER}"`
if [ $? -ne 0 ] || [ -z "$env_file_list" ]; then
    log_error "Get user env file failed"
    exit "$RETURN_INVALID"
fi

EXPORT_ORACLE_ENV=`generate_export_cmd "$env_file_list" "oracle"`
if [ $? -ne 0 ] || [ -z "$EXPORT_ORACLE_ENV" ]; then
    log_error "Get user env cmd failed"
    exit "$RETURN_INVALID"
fi

# check oracle install
check_oracle_is_install

# check oracle install type
check_oracle_install_type

if [ "$DBISCLUSTER" -gt 0 ]; then
    # get grid user
    get_grid_user
    get_grid_user_shell_type
    get_grid_home_path

    env_file_list=`get_user_env_file "${ORA_GRID_USER}"`
    if [ $? -ne 0 ] || [ -z "$env_file_list" ]; then
        log_error "Get user env file failed"
        exit "$RETURN_INVALID"
    fi

    EXPORT_GRID_ENV=`generate_export_cmd "$env_file_list" "grid"`
    if [ $? -ne 0 ] || [ -z "$EXPORT_GRID_ENV" ]; then
        log_error "Get user env cmd failed"
        exit "$RETURN_INVALID"
    fi
fi

#get oracle base path
get_oracle_base_path

#get oracle home path
get_oracle_home_path

#get oracle version
get_oracle_version

check_sqlplus_status

check_rman_status

DBINSTANCE=`get_real_instance_name "${DBINSTANCE}"`
test -z "${DBINSTANCE}"                                    && exit_with_error "DB real instance name"
log_info "Check cluster [DBISCLUSTER=${DBISCLUSTER}], DBINSTANCE=${DBINSTANCE}."

base_info=`get_database_base_info "${DBINSTANCE}" "${DBUSER}" "${DBUSERPWD}"`
if [ $? -ne 0 ] || [ -z "$base_info" ]; then
    log_error "Get database base info failed"
    exit $?
fi

info_num=`echo "${base_info}" | $MYAWK '{print NF}'`
log_mode=`echo "${base_info}" | $MYAWK '{print $1}'`
db_id=`echo "${base_info}" | $MYAWK '{print $2}'`
uniq_dbname=`echo "${base_info}" | $MYAWK '{print $3}'`
if [ "$info_num" -gt 7 ]; then
    open_mode=`echo "${base_info}" | $MYAWK '{print $4$5$6$7}'`
    resetlogs_id=`echo "${base_info}" | $MYAWK '{print $9}'`
elif [ "$info_num" -eq 7 ]; then
    open_mode=`echo "${base_info}" | $MYAWK '{print $4$5}'`
    resetlogs_id=`echo "${base_info}" | $MYAWK '{print $7}'`
else
    open_mode=`echo "${base_info}" | $MYAWK '{print $4}'`
    resetlogs_id=`echo "${base_info}" | $MYAWK '{print $6}'`
fi


if [ "${log_mode}" != "ARCHIVELOG" ]; then
    log_error "Archive Mode=No Archive Mode, check archive mode failed."
    exit "${ERROR_ORACLE_NOARCHIVE_MODE}"
fi

create_dir "${ARCHIVE}/resetlogs_id${resetlogs_id}"
check_dir_rwx "$ORA_DB_USER" "${ARCHIVE}/resetlogs_id${resetlogs_id}"       || exit_with_error "check log path"
check_dir_rwx "$ORA_DB_USER" "$IN_ORACLE_HOME"                              || exit_with_error "check oracle home path"
LOG_IS_BACKED_UP="$LOG_IS_VALID and (name like '$ARCHIVE/resetlogs_id${resetlogs_id}/arch_%' or name like '/tmp/advbackup/log/${DBUUID}/resetlogs_id${resetlogs_id}/arch_%')"

#********************************prepare for backup begin********************************
# from scn
log_info "Begin to exec SQL Get From Scn"

if [ -n "${LAST_BACKUP_SCN}" ]; then
    if [ "${LAST_BACKUP_RESET_LOGS_ID}" != "${resetlogs_id}" ]; then
        log_error " last_backup_resetlogs_id(${LAST_BACKUP_RESET_LOGS_ID}) not match current resetlogs_id(${resetlogs_id}), backup data first."
        exit "${ERROR_LOST_FULL_BACKUP}"
    fi
    from_scn=${LAST_BACKUP_SCN}
    log_info "last_backup_scn=${from_scn}"
else
    last_log_info=`get_last_log_scn "${DBINSTANCE}" "${DBUSER}" "${DBUSERPWD}"`
    from_scn=`echo "$last_log_info" | ${MYAWK} '{print $1}'`
    if [ $? -ne 0 ] || [ -z "${from_scn}" ]; then
        log_error "Get Last archive log failed"
        exit "${RETURN_INVALID}"
    fi
    log_info "Last backup archive log is ${from_scn}."
fi

node_list=`get_database_node_list "${DBINSTANCE}" "${DBUSER}" "${DBUSERPWD}"`
if [ $? -ne 0 ];then
    log_error "Get database node list failed"
    exit "$RETURN_INVALID"
fi

logNum=`get_archive_log_num "${DBINSTANCE}" "${DBUSER}" "${DBUSERPWD}" "${from_scn}" "/mnt/databackup" `
log_info "GetArchiveLogNum=${logNum}"

check_standby_database_sequence "${DBINSTANCE}" "${DBUSER}" "${DBUSERPWD}"
ret_code=$?
if [ $ret_code -ne 0 ]; then
    log_error "The max sequence of primary and standby database is not consistent!"
    exit "${ERROR_PRIMARY_STANDBY_DIFFERENT}"
fi

#********************************prepare for backup end********************************

#********************************backup log file begin********************************
log_info "Building RMAN Log backup script"
backup_archive_log_sql="${STMP_PATH}/backup_archive_log_sql_${PID}.sql"
backup_archive_log_rst="${STMP_PATH}/backup_archive_log_rst_${PID}.txt"

build_backup_archive_log_sql "$backup_archive_log_sql" "$logNum"
log_info "Running RMAN to backup archive logs"

chown "${ORA_DB_USER}" "${backup_archive_log_sql}"
chmod 700 "${backup_archive_log_sql}"

rman_exe_script "${DBUSER}" "${DBUSERPWD}" "${backup_archive_log_sql}" "${backup_archive_log_rst}" "${DBINSTANCE}" -1 1
ret_code=$?
if [ ${ret_code} -ne 0 ]; then
    log_error "Backup database-${DBINSTANCE} archive log failed  code is ${ret_code}"
    delete_file "${backup_archive_log_sql}" "${backup_archive_log_rst}" "true"
    if [ "${ERROR_SCRIPT_EXEC_FAILED}" = "${ret_code}" ]; then
        exit "${ERROR_ORACLE_BACKUP_FAILED}"
    fi
    exit ${ret_code}
fi

log_info "Backup database-${DBINSTANCE} archive log succ."
delete_file "${backup_archive_log_sql}" "${backup_archive_log_rst}" "true"
#********************************backup log file begin********************************

#********************************after backup log file begin******************************


#get archive log range
get_archivelog_current_range "${DBINSTANCE}" "${DBUSER}" "${DBUSERPWD}"

logbackuprst=`get_all_archivelog_range`
echo "${logbackuprst}" >> "${RESULT_FILE}"


#chmod 640 RESULT_FILE
if [ -f  "${RESULT_FILE}" ]; then
    chmod 640 "${RESULT_FILE}"
fi

rm -rf "${ARCHIVE}"/last_backup_scn >> "${LOG_FILE_NAME}" 2>&1

# 将日志记录置为无效，以免被其他备份任务使用
change_archive_log_unavailable "log"

log_info "Do log backup success."
